﻿#region imports

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

using CondeNet.AssetManager.Data;
using CondeNet.AssetManager.Business;
using CondeNet.AssetManager.Business.Interface;
using CondeNet.AssetManager.Business.Model;
using CondeNet.AssetManager.Business.Model.Interface;

using CondeNet.AssetManager.ProviderServices;
using CondeNet.AssetManager.ProviderServices.Data;
using CondeNet.AssetManager.ProviderServices.DataModel;
using CondeNet.AssetManager.DataProvider.Sql;
using CondeNet.AssetManager.DataProvider.Sql.Mappers;

#endregion

namespace CondeNet.AssetManager.DataProvider.Sql.Models
{
    public class AssetModelProvider : IAssetModelReaderFactory 
    {
        #region privates

        private IAssetReaderFactory readDB;

        #endregion

        #region constructors

        public AssetModelProvider ( )
        {
            readDB = AssetManagerConfig.GetAssetReaderProvider ( );
        }

        #endregion

        #region MetaData - integrated

        public IMetaData GetMetaDataByID ( int metaDataId )
        {
            return BuildMetaData ( readDB.GetMetaDataByID ( metaDataId ) );
        }
        public List<IMetaData> GetAllMetaData ( )
        {
            return BuildMetaDataList ( readDB.GetAllMetaData ( ) );
        }
        public List<IMetaData> GetMetaDataByLanguageID ( int languageId )
        {
            return BuildMetaDataList ( readDB.GetMetaDataByMetaValueLanguageID ( languageId ) );
        }
        private IMetaData BuildMetaData ( IMetaData metaData )
        {
            // get the MetaKey and MetaValue for the MetaData object we are constructing
            MetaValue metaValue = ( MetaValue ) readDB.GetMetaValueByID ( metaData.MetaValueID );
            MetaKey metaKey = ( MetaKey ) readDB.GetMetaKeyByID ( metaData.MetaKeyID );

            if ( ( metaValue != null ) && ( metaKey != null ) )
                return new MetaData ( metaData , metaKey , metaValue );

            else if ( metaValue != null )
                return new MetaData ( metaData , metaValue );

            else if ( metaKey != null )
                return new MetaData ( metaData , metaKey );

            else
                return new MetaData ( metaData );
        }
        private List<IMetaData> BuildMetaDataList ( IList<IMetaData> metaDataList )
        {
            List<IMetaData> l = new List<IMetaData> ( );

            foreach ( MetaData metaData in metaDataList )
            {
                l.Add ( BuildMetaData ( metaData ) );
            }

            return l;
        }

        #endregion

        #region AssetMetaData - integrated
        public IAssetMetaData GetAssetMetaDataByID ( int assetMetaDataId )
        {
            return BuildAssetMetaData ( readDB.GetAssetMetaDataByID ( assetMetaDataId ) );
        }
        public List<IAssetMetaData> GetAllAssetMetaData ( )
        {
            return BuildAssetMetaDataList ( readDB.GetAllAssetMetaData ( ) );
        }
        public List<IAssetMetaData> GetAssetMetaDataByAssetID ( int assetId )
        {
            return BuildAssetMetaDataList ( readDB.GetAssetMetaDataByAssetID ( assetId ) );
        }
        public List<IAssetMetaData> GetAssetMetaDataByAssetIDStatusID ( int assetId , int statusId )
        {
            return BuildAssetMetaDataList ( readDB.GetAssetMetaDataByAssetIDStatusID ( assetId , statusId ) );
        }
        public List<IAssetMetaData> GetAssetMetaDataByAssetIDLanguageID ( int assetId , int languageId )
        {
            return BuildAssetMetaDataList ( readDB.GetAssetMetaDataByAssetIDLanguageID ( assetId , languageId ) );
        }
        private AssetMetaData BuildAssetMetaData ( IAssetMetaData assetMetaData )
        {
            // Get the MetaData for the AssetMetaData we are constructing
            IMetaData metaData = BuildMetaData ( readDB.GetMetaDataByID ( assetMetaData.MetaDataID ) );

            if ( metaData != null ) return new AssetMetaData ( assetMetaData , metaData );
            else return new AssetMetaData ( assetMetaData );
        }
        private List<IAssetMetaData> BuildAssetMetaDataList ( IList<IAssetMetaData> assetMetaDataList )
        {
            List<IAssetMetaData> l = new List<IAssetMetaData> ( );

            foreach ( AssetMetaData amd in assetMetaDataList )
            {
                l.Add ( BuildAssetMetaData ( amd ) );
            }

            return l;
        }

        #endregion

        #region AssetContent - integrated

        public IAssetContent GetAssetContentByID ( int assetContentId )
        {
            return BuildAssetContent ( readDB.GetAssetContentByID ( assetContentId ) );
        }
        public List<IAssetContent> GetAssetContentByAssetID ( int assetId )
        {
            return BuildAssetContentList ( readDB.GetAssetContentByAssetID ( assetId ) );
        }
        private AssetContent BuildAssetContent ( IAssetContent assetContent )
        {
            AssetContent a = new AssetContent ( assetContent );

            IAssetContentType assetContentType = readDB.GetAssetContentTypeByID ( assetContent.AssetContentTypeID );
            IMimeType mimeType = readDB.GetMimeTypeByID ( assetContent.MimeTypeID );
            List<IAssetContentMetaData> assetContentMetaDataList = GetAssetContentMetaDataListByAssetContentID ( assetContent.AssetID );
            List<IAssetContentRepository> assetContentRepositoryList = GetAssetContentRepositoryListByAssetContentID ( assetContent.AssetID );

            if ( assetContentType != null ) a.AssetContentType = assetContentType;
            if ( mimeType != null ) a.MimeType = mimeType;
            a.AssetContentMetaDataList = assetContentMetaDataList;
            a.AssetContentRepositoryList = assetContentRepositoryList;

            return a;
        }
        private List<IAssetContent> BuildAssetContentList ( IList<IAssetContent> assetContentList )
        {
            List<IAssetContent> l = new List<IAssetContent> ( );

            foreach ( IAssetContent item in assetContentList ) l.Add ( BuildAssetContent ( item ) );

            return l;
        }

        #endregion

        #region Asset - integrated

        public IAsset GetAssetByID ( int assetId )
        {
            return BuildAsset ( readDB.GetAssetByID ( assetId ) );
        }
        public List<IAsset> GetAllAsset ( )
        {
            return BuildAssetList ( readDB.GetAllAsset ( ) );
        }
        private IAsset BuildAsset ( IAsset asset ) 
        { 
            Asset a = new Asset ( asset );
            
            a.RelatedAssetList = readDB.GetRelatedAssetByAssetID ( asset.ID );
            a.AssetRightsUsageList = readDB.GetAssetRightsUsageByAssetID ( asset.ID );
            a.AssociatedContentList = readDB.GetAssociatedContentByAssetID ( asset.ID );
            a.AssetMetaDataList = GetAssetMetaDataByAssetID ( asset.ID );
            a.AssetContentList = GetAssetContentByAssetID ( asset.ID );

            return a;
        }
        private List<IAsset> BuildAssetList ( IList<IAsset> assetList )
        {
            List<IAsset> l = new List<IAsset> ( );

            foreach ( IAsset item in assetList ) l.Add ( BuildAsset ( item ) );

            return l;
        }

        #endregion

        #region AssetContentMetaData - integrated

        private List<IAssetContentMetaData> GetAssetContentMetaDataListByAssetContentID ( int assetContentId )
        {
            return BuildAssetContentMetaDataList ( readDB.GetAssetContentMetaDataByAssetContentID ( assetContentId ) );
        }
        private IAssetContentMetaData BuildAssetContentMetaData ( IAssetContentMetaData assetContentMetaData )
        {
            IMetaData metaData = GetMetaDataByID ( assetContentMetaData.MetaDataID );

            if ( metaData != null ) return new AssetContentMetaData ( assetContentMetaData, metaData );
            else return new AssetContentMetaData ( assetContentMetaData );
        }
        private List<IAssetContentMetaData> BuildAssetContentMetaDataList ( IList<IAssetContentMetaData> assetContentMetaDataList )
        {
            List<IAssetContentMetaData> l = new List<IAssetContentMetaData> ( );

            foreach ( IAssetContentMetaData item in assetContentMetaDataList ) l.Add ( BuildAssetContentMetaData ( item ) );

            return l;
        }

        #endregion

        #region AssetContentRepository - integrated

        public List<IAssetContentRepository> GetAssetContentRepositoryListByAssetContentID ( int assetContentId )
        {
            return BuildAssetContentRepositoryList ( readDB.GetAssetContentRepositoryByAssetContentID ( assetContentId ) );
        }
        public IAssetContentRepository GetAssetContentRepositoryByID ( int Id )
        {
            return BuildAssetContentRepository ( readDB.GetAssetContentRepositoryByID ( Id ) );
        }
        private IAssetContentRepository BuildAssetContentRepository ( IAssetContentRepository assetContentRepository )
        {
            IRepository repository = readDB.GetRepositoryByID ( assetContentRepository.RepositoryID );

            if ( repository != null ) return new AssetContentRepository ( assetContentRepository , repository );
            else return new AssetContentRepository ( assetContentRepository );
        }
        private List<IAssetContentRepository> BuildAssetContentRepositoryList ( IList<IAssetContentRepository> assetContentRepository )
        {
            List<IAssetContentRepository> assetContentRepositoryList = new List<IAssetContentRepository> ( );

            foreach ( IAssetContentRepository item in assetContentRepositoryList ) assetContentRepositoryList.Add ( BuildAssetContentRepository ( item ) );

            return assetContentRepositoryList;
        }

        #endregion
    }
}